#include "pwext.hpp"
#include <stdio.h>
#include <stdlib.h>

#ifndef EX05_NESTED
#include "ex05fc.cpp"
#endif // EX05_NESTED

// [[ex05ff]]
// DEBUG descr The temporary release and re-grabbing of the weak references.
template <typename target>
class scopegrab
{
public:
	scopegrab(weakref *ref, target *&result) : 
		ref_(ref)
	{
		result = (target *)ref->grab();
		grabbed_ = true;
	}
	~scopegrab()
	{
		if (grabbed_)
			ref_->release();
	}
	void release()
	{
		if (grabbed_)
			ref_->release();
		grabbed_ = false;
	}
	target *regrab()
	{
		if (grabbed_)
			ref_->release();
		grabbed_ = true;
		return (target *)ref_->grab();
	}
protected:
	weakref *ref_;
	bool grabbed_;
private: 
	// prevent the default and copy constructors and
	// assignments
	scopegrab();
	scopegrab(const scopegrab &);
	void operator=(const scopegrab &);
};
// END

#ifndef EX05_NESTED
// DEBUG from
class mytarget : public reftarget
{
public:
	mytarget() :
		reftarget(this)
	{ }

	~mytarget()
	{
		invalidate();
	}
};

int main()
{
	mytarget *t = new mytarget;
	weakref *r = t->newweakref();
	{
		mytarget *tt;
		scopegrab<mytarget> scope(r, tt);
		if (tt) {
			fprintf(stderr, "target is still valid\n");
		}
		scope.release();
		delete t;
		tt = scope.regrab();
		if (!tt) {
			fprintf(stderr, "target is not valid any more\n");
		}
	}
	return 0;
}

/* Sample result:
target is still valid
target is not valid any more
*/
#endif // EX05_NESTED
